package com.wondersgroup.core.util;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component  
@Aspect 
public class CacheAop {
  
    @Around("execution(* com.wondersgroup.core.service.*.*(..))")  
    public Object doAround(ProceedingJoinPoint call){  
         Object result = null;  
         Method[] methods = call.getTarget().getClass().getDeclaredMethods();    
         Signature signature = call.getSignature();  
         MethodSignature methodSignature = (MethodSignature) signature;    
         Method method = methodSignature.getMethod();  
         for(Method m:methods){//循环方法，找匹配的方法进行执行  
             if(m.getName().equals(method.getName())){  
                 if(m.isAnnotationPresent(Cache.class)){
                     Cache cache = m.getAnnotation(Cache.class); 
                     if(cache!=null){  
                         	String tempKey = this.getKey(call.getTarget().getClass().getSimpleName(), method, call.getArgs());  
                            String prefix = cache.key();  
                            String key = "";  
                            if(prefix!=null && !"".equals(prefix)){
                            	key = prefix+"_"+tempKey;
                            }else{
                            	key = tempKey;
                            }
                         	result =Memcache.get(key);  
                            if(null == result){  
                                try {  
                                	System.out.println("CacheAop------Cache--------add-------"+key+"----------"); 
                                 	result = call.proceed();  
                                    Memcache.set(key, cache.expiration(), result); 
                                } catch (Throwable e) {  
                                    e.printStackTrace();  
                                }  
                            }  
                              
                        }  
                } else  if(method.isAnnotationPresent(Flush.class)){  
                     Flush flush = method.getAnnotation(Flush.class);  
                     if(flush!=null){  
                    	 String[] keys = flush.key();  
                     	 for(String key : keys){
                     		 //删除缓存  
                     		 System.out.println("CacheAop--------------------Flush--------do-----------------------------------"); 
                         	 if(!StringUtils.isEmpty(key)){
                     			Memcache.delete(key);
                     		 }
                     	 } 
                     }  
                     try {  
                         result = call.proceed();  
                        } catch (Throwable e) {  
                            e.printStackTrace();  
                        }
                 }else{  
                     try {  
                         result = call.proceed();  
                        } catch (Throwable e) {  
                            e.printStackTrace();  
                        }  
                 }  
                 break;  
             }  
        }  
        return result;  
    }  
      
    /** 
     * 组装key值 
     * @param method 
     * @param args 
     * @return 
     */  
   private String getKey(String className, Method method, Object [] args){  
        StringBuffer sb = new StringBuffer();
        sb.append(className).append("_");
        String methodName = method.getName();  
        sb.append(methodName);  
        if(args!=null && args.length>0){  
            for(Object arg:args){ 
            	if(arg==null||StringUtils.isEmpty(arg)){
            		sb.append("_null");  
            	}else{
            		sb.append("_"+arg);  
            	}
            }  
        }  
        return sb.toString();  
   } 
}
